package cn.myzf.module.routes;

import cn.myzf.module.annotation.NettyController;
import cn.myzf.module.annotation.NettyRequestMapping;
import cn.myzf.module.instance.ControllerInstance;
import cn.myzf.module.interceptor.AuthInterceptor;
import cn.myzf.module.interceptor.NettyInterceptor;
import io.netty.handler.codec.http.FullHttpRequest;
import io.netty.handler.codec.http.HttpMethod;

import java.io.File;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.lang.reflect.Method;
import java.net.URLDecoder;
import java.util.*;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;

/**
 * @package cn.myzf.module.routes
 * @Date Created in 2020/3/7 22:22
 * @Author myzf
 */
public abstract class HttpServlet<T> {



    private String projectPath = this.getClass().getResource("/").getPath();
    private String prefix = "";
    private String suffix = "";
    protected Map<String,Method> methodMap = new HashMap(); //url和method映射关系

    /** 拦截器，初始化后不会在变化 */
    protected static List<NettyInterceptor> interceptors = new ArrayList<>();

    protected ControllerInstance controllerInstance;

    private boolean enabled = true;//默认开启拦截器

    public void setEnabled(boolean enabled) {
        this.enabled = enabled;
    }

    public HttpServlet() {
        addInterceptor(new AuthInterceptor());
        projectPath = getPath();
        String packagePath = projectPath.replaceAll("%20","");//解决路径中含有空格的情况
        scanProjectByPath(projectPath+"/");
    }



    public void setControllerInstance(ControllerInstance controllerInstance) {
        this.controllerInstance = controllerInstance;
    }

    protected abstract void doInterceptor(FullHttpRequest request);//指定拦截器

    /**
     * 手动增加拦截器
     *
     * @param
     */
    public static void addInterceptor(NettyInterceptor nettyInterceptor) {
        if (interceptors.contains(nettyInterceptor)) {
            throw new IllegalArgumentException("Duplicate NettyInterceptor:" + nettyInterceptor);
        }
        interceptors.add(nettyInterceptor);
    }


    public T doDispatcher(FullHttpRequest request){
        if(enabled){
            doInterceptor(request);
        }
        if (request.getMethod() != HttpMethod.POST) {
           return doGet(request);
        }else {
         return  doPost(request);
        }
    }

    protected T doGet(FullHttpRequest request){
      return doPost(request);
    }


    protected T doPost(FullHttpRequest request){

        return null;
    }



    public void scanProjectByPath(String path){
        File file = new File(path);
        scanFile(file);
    }




    public String getPath()
    {
        String path = this.getClass().getProtectionDomain().getCodeSource().getLocation().getPath();
        if(System.getProperty("os.name").contains("dows"))
        {
            path = path.substring(1,path.length());
        }
        if(path.contains("jar"))
        {
            path = path.substring(0,path.lastIndexOf("."));
            return path.substring(0,path.lastIndexOf("/"));
        }
        return path.replace("target/classes/", "");
    }

    public void scanFile(File file)  {
        if (file.isDirectory()) {
            for (File file1 : file.listFiles()) {
                scanFile(file1);
            }
        }else{
            String path = file.getPath();
            if (path.substring(path.lastIndexOf(".")).equals(".jar")) {
                JarFile jarFile = null;
                try {
                    jarFile = new JarFile(file);
                } catch (IOException e) {
                    e.printStackTrace();
                }
                Enumeration<JarEntry> entries = jarFile.entries();
                while (entries.hasMoreElements()) {
                    //            if (path.substring(path.lastIndexOf(".")).equals(".class")){
                    // com\\controller\\TestController.class
                    String elementName = entries.nextElement().toString();
//                    String classPath  =  path.replace(new File(projectPath).getPath()+"\\","");
                    String classPath = elementName.replaceAll("/",".");

                    String className = classPath.substring(0,classPath.lastIndexOf("."));
                    int i = classPath.lastIndexOf(".");
                    if (i!=-1&&classPath.substring(i).equals(".class")){
                        try {
                            Class<?> clazz = Class.forName(className);
                            //@Resources  == @Controller
                            boolean annotationPresent = clazz.isAnnotationPresent(NettyController.class);
                            //ResourcesMapping==@RequestMapping
                            if (annotationPresent){
                                NettyRequestMapping annotation = clazz.getAnnotation(NettyRequestMapping.class);

                                String classRequestMappingPath = "";
                                if (annotation != null) {
                                    classRequestMappingPath = annotation.value();
                                }
                                //解析所有方法
                                for (Method method : clazz.getMethods()) {
                                    NettyRequestMapping methodResourcesMapping = method.getAnnotation(NettyRequestMapping.class);
                                    if (methodResourcesMapping != null) {
                                        String requestMapping = methodResourcesMapping.value();
                                        methodMap.put(classRequestMappingPath+requestMapping,method);
                                    }
                                }
                            }
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                    }


//            }

                }




            }

            //....class    Class
            //c://project//luban//test-mvc//java//com//controler//TestController.class
            //Class.forName(className)
            //className: com.controller.TestController
            /**
             * 正在模拟Spring MVC 初始化代码
             */

        }
    }




        public static void main(String[] args) throws Exception{
            JarFile jarFile = null;
            try {
                jarFile = new JarFile(new File("c:\\repository\\myzf-register-center\\myzf-server\\0.0.1-SNAPSHOT\\myzf-server-0.0.1-SNAPSHOT.jar"));
            } catch (IOException e) {
                e.printStackTrace();
            }
            Enumeration<JarEntry> entries = jarFile.entries();
            while (entries.hasMoreElements()){
                System.out.println(entries.nextElement().toString());
            }
        }






}
